import * as cc from 'cc';
import PageView from './PageView';

export enum PageViewIndicatorDirection {
    HORIZONTAL = 1,
    VERTICAL = 2
}

export enum PageViewIndicatorType {
    /** 通过图片区分 */
    SpriteFrame = 1,
    /** 通过颜色区分 */
    Color = 2,
}

const { ccclass, property, menu } = cc._decorator;
@ccclass("PageViewIndicator")
@menu("扩展组件/PageViewIndicator")
export default class PageViewIndicator extends cc.Component {

    @property({ type: cc.Enum(PageViewIndicatorDirection), tooltip: "方向" })
    direction: PageViewIndicatorDirection = PageViewIndicatorDirection.HORIZONTAL;

    @property({ type: cc.Enum(PageViewIndicatorType), tooltip: "显示点类型" })
    pageViewIndicatorType: PageViewIndicatorType = PageViewIndicatorType.SpriteFrame;

    @property({ type: cc.SpriteFrame, tooltip: "使用图片", })
    spriteFrame: cc.SpriteFrame = null;
    @property({ type: cc.SpriteFrame, tooltip: "选中图", visible() { return this.pageViewIndicatorType === PageViewIndicatorType.SpriteFrame } })
    spriteFrameSelect: cc.SpriteFrame = null;

    @property({ tooltip: "正常大小", visible() { return this.pageViewIndicatorType === PageViewIndicatorType.Color } })
    colorNormal: cc.Color = cc.color(255, 255, 255);
    @property({ tooltip: "选中大小", visible() { return this.pageViewIndicatorType === PageViewIndicatorType.Color } })
    colorSelect: cc.Color = cc.color(255, 0, 0);

    @property({ tooltip: "正常大小" })
    scaleNormal: number = 1;
    @property({ tooltip: "选中大小" })
    scaleSelect: number = 1.2;

    @property({ tooltip: "页面标记大小" })
    cellSize: cc.Size = cc.size(10, 10);

    @property({ tooltip: "页面标记间隔" })
    spacing: number = 10;

    _indicators: cc.Sprite[] = [];
    _pageView: PageView = null;
    _layout: cc.Layout = null;

    _maxCount: number = 0;
    onLoad() {
        this._updateLayout();
    }

    /**
     * @en
     * Set Page View.
     *
     * @zh
     * 设置页面视图。
     *
     * @param target @en The page view which is attached with this indicator.  @zh 当前标记对象附着到的页面视图对象。
     */
    public setPageView(target: PageView) {
        this._pageView = target;

        switch (this.direction) {
            case PageViewIndicatorDirection.HORIZONTAL:
                this._maxCount = this._pageView.viewSize.width / (this.cellSize.width + this.spacing)
                break;
            case PageViewIndicatorDirection.VERTICAL:
                this._maxCount = this._pageView.viewSize.height / (this.cellSize.height + this.spacing)
                break;
        }
        this._refresh();
    }

    /**
     * @desc 更新状态
     */
    public updateState() {
        this._changedState();
    }

    /**
     * @desc 初始化layout
     */
    private _updateLayout() {
        this._layout = this.node.getComponent(cc.Layout) || this.node.addComponent(cc.Layout);

        const layout = this._layout!;
        if (this.direction === PageViewIndicatorDirection.HORIZONTAL) {
            layout.type = cc.Layout.Type.HORIZONTAL;
            layout.spacingX = this.spacing;
        } else if (this.direction === PageViewIndicatorDirection.VERTICAL) {
            layout.type = cc.Layout.Type.VERTICAL;
            layout.spacingY = this.spacing;
        }
        layout.resizeMode = cc.Layout.ResizeMode.CONTAINER;
    }

    /**
     * @desc 创建节点
     */
    private _createIndicator() {
        const node = new cc.Node();
        node.layer = this.node.layer;
        const sprite = node.addComponent(cc.Sprite);
        sprite.spriteFrame = this.spriteFrame;
        sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM;
        node.parent = this.node;
        const uiTrans = node.getComponent(cc.UITransform) || node.addComponent(cc.UITransform);
        uiTrans.setContentSize(this.cellSize);
        return sprite;
    }

    /**
     * @desc 更新标签状态
     */
    private _changedState() {
        const indicators = this._indicators;
        if (indicators.length === 0 || !this._pageView) { return; }
        const idx = Math.max(Math.min(indicators.length - 1, this._pageView.curPageIdx), 0);

        for (let i = 0; i < indicators.length; ++i) {
            const sprite = indicators[i];
            const isSelect = i == idx;
            const scale = isSelect ? this.scaleSelect : this.scaleNormal;
            sprite.node.setScale(scale, scale, 1);
            switch (this.pageViewIndicatorType) {
                case PageViewIndicatorType.SpriteFrame:
                    const spriteFrame = isSelect ? this.spriteFrameSelect : this.spriteFrame;
                    sprite.spriteFrame = spriteFrame;
                    break;
                case PageViewIndicatorType.Color:
                    const color = isSelect ? this.colorSelect : this.colorNormal;
                    sprite.color = color;
                    break;
            }
        }
    }

    /**
     * @desc 刷新
     */
    private _refresh() {
        if (!this._pageView) { return; }
        const indicators = this._indicators;
        if (this._maxCount === indicators.length) {
            return;
        }
        let i = 0;
        if (this._maxCount > indicators.length) {
            for (i = 0; i < this._maxCount; ++i) {
                if (!indicators[i]) {
                    indicators[i] = this._createIndicator();
                }
            }
        } else {
            const count = indicators.length - this._maxCount;
            for (i = count; i > 0; --i) {
                if (indicators[i - 1]) {
                    const node = indicators[i - 1].node;
                    this.node.removeChild(node);
                }

                indicators.splice(i - 1, 1);
            }
        }
        if (this._layout && this._layout.enabledInHierarchy) {
            this._layout.updateLayout();
        }
        this._changedState();
    }
}